<template>
  <div class="container">
    <div class="app-container">
      <div class="role-operate">
        <el-button type="primary" @click="addRoleVisible = true">添加角色</el-button>
      </div>
      <el-table :data="roleList" style="width: 100%" border>
        <el-table-column prop="name" width="200px" label="角色名称" align="center">
          <template v-slot="{ row }">
            <el-input v-model="row.editRow.name" v-if="row.isEdit" size="mini"></el-input>
            <span v-else>{{ row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="state" width="200px" label="启用" align="center">
          <template v-slot="{ row }">
            <el-switch v-if="row.isEdit" v-model="row.editRow.state" :active="1" :inactive="0" active-color="#13ce66" size="mini"></el-switch>
            <span v-else>{{ row.state === 1 ? "已启用" : row.state === 0 ? "未启用" : "无" }} </span>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="描述" align="center">
          <template v-slot="{ row }">
            <el-input v-model="row.editRow.description" type="textarea" :rows="2" v-if="row.isEdit"></el-input>
            <span v-else>{{ row.description }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center">
          <template v-slot="{ row }">
            <!-- 编辑状态 -->
            <template v-if="row.isEdit">
              <el-button type="primary" size="small" @click="editRoleConcelBtn(row)">确认</el-button>
              <el-button size="small" @click="row.isEdit = false">取消</el-button>
            </template>
            <!-- 非编辑状态 -->
            <template v-else>
              <el-button type="primary" text="primary" size="small" @click="assignPermissionBtn(row)">分配权限</el-button>
              <el-button type="success" text="success" size="small" @click="editRoleRow(row)">编辑</el-button>
              <el-popconfirm title="确定删除角色吗?" confirm-button-text="确定" cancel-button-text="取消" @confirm="delRoleBtn(row)">
                <template #reference>
                  <el-button type="danger" text="plain" size="small">删除</el-button>
                </template>
              </el-popconfirm>
            </template>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页器 -->
      <el-row type="flex" style="height: 60px" justify="end" align="middle">
        <el-pagination v-model:current-page="pageParam.page" v-model:page-size="pageParam.pagesize" :page-sizes="[5, 10, 15, 20]" :size="size" layout="sizes, prev, pager, next, jumper,total" :total="pageParam.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
      </el-row>
    </div>
    <!-- 添加角色对话框内容区域 -->
    <el-dialog v-model="addRoleVisible" title="添加角色" :before-close="btnConcelClick" width="30%">
      <el-form ref="addRoleRef" :model="addRoleForm" :rules="addRoleRules" label-width="100" style="max-width: 400px">
        <el-form-item label="角色名称" prop="name">
          <el-input placeholder="请输入角色名称" v-model="addRoleForm.name"> </el-input>
        </el-form-item>
        <el-form-item label="启用">
          <el-switch v-model="addRoleForm.state" :active-value="1" :inactive-value="0" active-color="#13ce66" size="mini" />
        </el-form-item>
        <el-form-item label="角色描述" prop="description">
          <el-input placeholder="请输入角色描述" type="textarea" :row="4" v-model="addRoleForm.description"> </el-input>
        </el-form-item>
        <el-row type="flex" justify="center">
          <el-col :span="12" class="col-center">
            <el-button type="primary" @click="addRoleBtnOkClick">确认</el-button>
            <el-button @click="btnConcelClick">取消</el-button></el-col
          >
        </el-row>
      </el-form>
    </el-dialog>
    <!-- 分配角色权限对话框 -->
    <el-dialog v-model="assignPerDialogVisible" title="分配权限" @close="closeBtn">
      <!-- 1先获取权限列表 2再获取角色已有权限点 -->
      <el-tree
        ref="permissionTreeRef"
        :data="permissionList"
        :props="{
          label: 'name',
        }"
        show-checkbox
        default-expand-all
        node-key="id"
        :default-checked-keys="permId">
      </el-tree>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeBtn">取消</el-button>
          <el-button type="primary" @click="assignPerBtnOk"> 确认 </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script lang="ts" setup>
import { onMounted } from "vue";
import { ref, reactive } from "vue";
import { useRoleStore } from "@/store/modules/role";
import { storeToRefs } from "pinia";
import { ElMessage } from "element-plus";
import { getRoleListApi, editRoleApi, getRoleDetailApi, assignPermApi } from "@/api/role";
import { getPermissionListApi } from "@/api/permission";
import { tranListToTreeData } from "@/utils/index";

onMounted(() => {
  // 获取角色列表数据
  getRoleListData();
});
const size = ref("default"); // 分页器大小选择器的尺寸
const pageParam = ref({ page: 1, pagesize: 5, total: 0 }); // 分页器参数
const addRoleVisible = ref(false); // 添加角色对话框显示隐藏状态变量
const roleStore = useRoleStore(); // 角色模块pinia仓库实例对象
const addRoleRef = ref(); // 添加角色表单ref引用对象
const roleList = ref([]);
const addRoleForm = reactive({
  name: "", // 角色名称
  description: "", // 角色描述信息
  state: 1, // 角色启用状态 1启用 0禁用 默认为1启用
}); // 添加角色表单数据对象
const currentRoleId = ref(null); // 当前选中角色id变量，用于分配权限时携带角色id参数到后端服务器进行更新角色权限操作
const permId = ref([]); // 角色已有权限点id数组

// 添加角色表单验证规则对象
const addRoleRules = {
  name: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
  description: [{ required: true, message: "请输入角色描述", trigger: "blur" }],
};
const assignPerDialogVisible = ref(false); // 分配角色权限对话框显示隐藏状态变量
const permissionList = ref([]); // 角色权限列表数据
const permissionTreeRef = ref(); // 权限树组件ref引用对象

// 初始化获取角色列表数据
const getRoleListData = async () => {
  const page = pageParam.value.page;
  const pagesize = pageParam.value.pageSize;
  const { rows, total } = await getRoleListApi({ page, pagesize });
  roleList.value = rows; // 初始化角色列表数据
  pageParam.value.total = total; // 初始化分页器总数据条数
  roleList.value.forEach((item) => {
    item.isEdit = false; // 初始化编辑状态为false vue3可以直接改响应式对象属性值，而Vue2不行，需要使用Vue.set()方法才行。
    item.editRow = {
      //初始化时缓存编辑行数据，以便编辑时使用
      name: item.name,
      description: item.description,
      state: item.state,
    };
  });
};

// 进入编辑状态行事件
const editRoleRow = (row) => {
  row.isEdit = !row.isEdit; // 修改编辑状态为true
  // 每次进入编辑状态时更新缓存数据，将原始数据缓存到editRow对象中
  row.editRow = {
    name: row.name,
    description: row.description,
    state: row.state,
  };
  console.log(roleList.value);
};
// 编辑状态更新角色确认事件
const editRoleConcelBtn = async (row) => {
  // 角色名称和角色描述都存在时才能更新角色信息
  if (row.editRow.name && row.editRow.description) {
    await editRoleApi({ ...row.editRow, id: row.id });
    row.isEdit = !row.isEdit; // 修改编辑状态为false
    ElMessage.success("更新角色成功");
    // 退出编辑状态，更新非编辑状态行显示的数据
    Object.assign(row, { ...row.editRow, isEdit: false });
  } else {
    ElMessage.error("角色信息不能为空!");
  }
};

// 添加角色确认按钮点击事件
const addRoleBtnOkClick = () => {
  addRoleRef.value.validate((valid: boolean) => {
    if (valid) {
      // 调用添加角色方法提交表单数据对象到后端服务器保存操作
      roleStore.addRoleAction(addRoleForm);
      btnConcelClick(); // 清空表单数据对象及重置表单验证状态与关闭对话框
      ElMessage.success("添加角色成功");
      // 重新获取角色列表数据刷新页面显示效果
      getRoleListData();
    } else {
      ElMessage.error("请输入完整信息");
    }
  });
};

const delRoleBtn = (row) => {
  roleStore.deleteRoleAction(row.id);
  ElMessage.success("删除角色成功");
  getRoleListData();
};
// 分配角色权限按钮点击事件
const assignPermissionBtn = async (row) => {
  // 记录当前选中角色id 用于分配权限时携带角色id参数到后端服务器进行更新角色权限操作
  currentRoleId.value = row.id;
  // 获取角色权限列表数据并转换为树形结构数据
  const res = tranListToTreeData(await getPermissionListApi(), 0);
  permissionList.value = res;
  // 获取角色已有权限点id数组数据
  const { permIds } = await getRoleDetailApi(row.id);
  permId.value = permIds;
  // 显示分配角色权限对话框
  assignPerDialogVisible.value = true;
  // tranListToTreeData()
};
// 分配角色权限确认按钮点击事件
const assignPerBtnOk = async () => {
  try {
    const checkedKeys = permissionTreeRef.value.getCheckedKeys();
    await assignPermApi({ permIds: checkedKeys, id: currentRoleId.value });
    ElMessage.success("更新角色成功");
    await getRoleListData();
    closeBtn();
  } catch (error) {
    ElMessage.error("更新角色权限失败");
  }
};
// 关闭分配角色权限对话框按钮点击事件
const closeBtn = () => {
  assignPerDialogVisible.value = false;
};

// 页码改变事件
const handleCurrentChange = (val: number) => {
  pageParam.value.page = val;
  getRoleListData();
};

// 页面大小改变事件
const handleSizeChange = (val: number) => {
  pageParam.value.pageSize = val;
  getRoleListData();
};

// 关闭添加角色弹窗
const btnConcelClick = () => {
  addRoleVisible.value = false;
  // 清空表单数据对象属性值
  for (const key in addRoleForm) {
    addRoleForm[key] = "";
  }
  //重置表单验证状态
  addRoleRef.value.resetFields();
};
</script>
<style lang="scss" scoped>
.role-operate {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 20px;
}
.col-center {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
